package com.charging.system.service.impl;

import java.math.BigDecimal;
import java.util.List;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.charging.common.constant.Constants;
import com.charging.common.utils.DateUtils;
import com.charging.system.domain.KxCard;
import com.charging.system.domain.KxChargingScheme;
import com.charging.system.domain.KxUserInfo;
import com.charging.system.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.charging.system.mapper.KxChargingRecordMapper;
import com.charging.system.domain.KxChargingRecord;

import javax.annotation.Resource;

/**
 * 充电记录Service业务层处理
 *
 * @author charging
 * @date 2024-04-19
 */
@Service
public class KxChargingRecordServiceImpl implements IKxChargingRecordService
{
    protected Logger logger = LoggerFactory.getLogger(getClass());
    @Resource
    private KxChargingRecordMapper kxChargingRecordMapper;
    @Resource
    private IKxChargingSchemeService kxChargingSchemeService;
    @Resource
    private IKxEquipService kxEquipService;
    @Resource
    private IKxUserInfoService kxUserInfoService;
    @Resource
    private IKxCardService kxCardService;

    /**
     * 查询充电记录
     *
     * @param chargingRecordId 充电记录主键
     * @return 充电记录
     */
    @Override
    public KxChargingRecord selectKxChargingRecordByChargingRecordId(Long chargingRecordId)
    {
        return kxChargingRecordMapper.selectKxChargingRecordByChargingRecordId(chargingRecordId);
    }

    /**
     * 查询充电记录列表
     *
     * @param kxChargingRecord 充电记录
     * @return 充电记录
     */
    @Override
    public List<KxChargingRecord> selectKxChargingRecordList(KxChargingRecord kxChargingRecord)
    {
        return kxChargingRecordMapper.selectKxChargingRecordList(kxChargingRecord);
    }

    /**
     * 新增充电记录
     *
     * @param kxChargingRecord 充电记录
     * @return 结果
     */
    @Override
    public int insertKxChargingRecord(KxChargingRecord kxChargingRecord)
    {
        kxChargingRecord.setCreateTime(DateUtils.getNowDate());
        return kxChargingRecordMapper.insertKxChargingRecord(kxChargingRecord);
    }

    /**
     * 修改充电记录
     *
     * @param kxChargingRecord 充电记录
     * @return 结果
     */
    @Override
    public int updateKxChargingRecord(KxChargingRecord kxChargingRecord)
    {
        kxChargingRecord.setUpdateTime(DateUtils.getNowDate());
        return kxChargingRecordMapper.updateKxChargingRecord(kxChargingRecord);
    }

    /**
     * 批量删除充电记录
     *
     * @param chargingRecordIds 需要删除的充电记录主键
     * @return 结果
     */
    @Override
    public int deleteKxChargingRecordByChargingRecordIds(Long[] chargingRecordIds)
    {
        return kxChargingRecordMapper.deleteKxChargingRecordByChargingRecordIds(chargingRecordIds);
    }

    /**
     * 删除充电记录信息
     *
     * @param chargingRecordId 充电记录主键
     * @return 结果
     */
    @Override
    public int deleteKxChargingRecordByChargingRecordId(Long chargingRecordId)
    {
        return kxChargingRecordMapper.deleteKxChargingRecordByChargingRecordId(chargingRecordId);
    }

    /**
     * 获取充电中的插座
     * @param kxChargingRecord
     * @return
     */
    @Override
    public List<Integer> getChargingChannelNos(KxChargingRecord kxChargingRecord) {
        return kxChargingRecordMapper.getChargingChannelNos(kxChargingRecord);
    }

    /**
     * 更新充电功率
     * @param kxChargingRecord
     * @return
     */
    @Override
    public int updateChargingPower(KxChargingRecord kxChargingRecord) {
        return kxChargingRecordMapper.updateChargingPower(kxChargingRecord);
    }

    @Override
    public List<Integer> getEquipChargingNos(String equipNo) {
        return kxChargingRecordMapper.getEquipChargingNos(equipNo);
    }

    /**
     * 按功率充电计费逻辑
     * @param kxChargingRecords
     */
    @Override
    public void chargingAction(List<KxChargingRecord> kxChargingRecords) {
        for(KxChargingRecord kxChargingRecord : kxChargingRecords){// 单条数据处理

            try{
                // 当前价格并获取当前的充电方案

                KxChargingScheme kxChargingScheme = kxChargingSchemeService.selectKxChargingSchemeByChargingSchemeId(kxChargingRecord.getChargingSchemeId());
                JSONArray schemes  =JSONArray.parseArray(kxChargingScheme.getSchemeDetailed());
                // 当前价格并获取当前的充电方案
                BigDecimal currentPrice =BigDecimal.ZERO;
                // 当前功率
//                Integer currentPower = 0;
//                Integer errorTimes = 0;//没有功率记录次数
//                if(null != channelAvgPowerMap){ // 没有获取功率，
//                    currentPower = Integer.parseInt(channelAvgPowerMap.get(""+kxChargingRecord.getChannelNo())) ;
//                }else {
//                    currentPower = kxChargingRecord.getChargingPower();
//                    errorTimes = kxChargingRecord.getErrorTimes()+1;
//                }
                Integer currentPower = kxChargingRecord.getChargingPower();
                // 最大功率
                Integer maxPower = currentPower > kxChargingRecord.getMaxChargingPower()?currentPower:kxChargingRecord.getMaxChargingPower();
                // 计算功率
                Integer power = 0;
                if(kxChargingScheme.getIsMaxPower()== Constants.YesOrNo.YES){// 最大功率计费
                    power = maxPower;
                }else {
                    power = currentPower;
                }

                // 算出当前功率范围的价格
                for (int i = 0; i<schemes.size();i++){
                    JSONObject scheme = schemes.getJSONObject(i);
                    Integer min_power = scheme.getIntValue("min_power");
                    Integer max_power = scheme.getIntValue("max_power");
                    if(power>=min_power&&power<max_power){
                        currentPrice = scheme.getBigDecimal("ele_price");
                    }
                }
                // 计算当前度数 1分钟消耗的度数 功率 kw/h 。当前为w 1分钟
                BigDecimal currentDegree = new BigDecimal(power).divide(new BigDecimal(1000*60),4,BigDecimal.ROUND_HALF_UP); //四舍五入

                // 如果超出范围功率范围时currentPrice = 0按度每分钟计费
                BigDecimal amount = BigDecimal.ZERO;

                if(currentPrice.compareTo(BigDecimal.ZERO)==0){// 超出设置的功率范围按度计算
                    amount = kxChargingScheme.getDegreePrice().multiply(currentDegree);
                }else {// 否则按功率计费
                    amount = currentPrice.divide(new BigDecimal(60),4,BigDecimal.ROUND_UP);
                }

                //如果有起充金额第一次计费amount大于0时直接消费起充金额，
                if(kxChargingRecord.getStartPrice().compareTo(BigDecimal.ZERO) ==1&&amount.compareTo(BigDecimal.ZERO)==1){//没有起充金额
                    logger.info("起充金额:"+kxChargingRecord.getStartPrice()+",本次计费金额："+amount+",已经计费："+kxChargingRecord.getAmount());
                    if(kxChargingRecord.getAmount().compareTo(BigDecimal.ZERO)==0){
                        kxChargingRecord.setAmount(kxChargingRecord.getStartPrice());
                    }else {
                        kxChargingRecord.setAmount(BigDecimal.ZERO);
                    }
                    kxChargingRecord.setStartPrice(kxChargingRecord.getStartPrice().subtract(amount));
                }else if(kxChargingRecord.getStartPrice().compareTo(BigDecimal.ZERO)==-1){// 起充金额小于0,设置为0
                    kxChargingRecord.setAmount(kxChargingRecord.getStartPrice().negate());
                    kxChargingRecord.setStartPrice(BigDecimal.ZERO);
                }else {
                    kxChargingRecord.setAmount(amount);
                }

//                kxChargingRecord.setErrorTimes(errorTimes);
                kxChargingRecord.setMaxChargingPower(maxPower);
                kxChargingRecord.setDegree(currentDegree.add(kxChargingRecord.getDegree()));
                kxChargingRecord.setChargingPower(currentPower);


                logger.info("equipNo:{},channelNo:{},accountId:{},cardId{},chargingSchemeId:{}," +
                                "已经计费次数:{},本次功率:{},本次最大功率:{},当前价格:{},当前度数:{},本次金额:{}"
                        ,kxChargingRecord.getEquipNo(),kxChargingRecord.getChannelNo(),kxChargingRecord.getUserId(),kxChargingRecord.getCardId(),kxChargingRecord.getChargingSchemeId(),
                        kxChargingRecord.getNumTimes(),currentPower,maxPower,currentPrice,currentDegree,amount);
                /**
                 * 计费
                 */
                int val = this.kxChargingRecordMapper.chargingMoney(kxChargingRecord);
                checkEndCharging(kxChargingRecord.getChargingRecordId(),kxChargingScheme.getMaxChargingTime(),kxChargingScheme.getIsPayLater()==Constants.YesOrNo.YES);

            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 判断是否达到充电结束条件
     * @param id 充电id
     * @param isOwe 是否可以欠费 true 后付款 false 先付款
     */
    public void checkEndCharging(Long id,Integer maxChargingTime, boolean isOwe ){
        /**
         * 判断是否达到主动关闭条件
         * 1、时间是否达到
         * 2、功率是否超出范围
         * 3、金额是否充足
         */
        // 获取计算后新的记录
        KxChargingRecord kxChargingRecordNew = this.kxChargingRecordMapper.selectKxChargingRecordByChargingRecordId(id);
        long chargingTimes = kxChargingRecordNew.getUpdateTime().getTime() - kxChargingRecordNew.getCreateTime().getTime();
        if(kxChargingRecordNew.getPlanChargingTime()==0){// 表示充满自停
            if(chargingTimes>= maxChargingTime*60*60*1000){//超过最长充电时间长
                kxEquipService.closeChannel(kxChargingRecordNew.getEquipNo(),kxChargingRecordNew.getChannelNo(),Constants.EndType.MaxChargingTime,true);
            }
        }else {//表示充电时长
            if(chargingTimes>= kxChargingRecordNew.getPlanChargingTime()*60*60*1000){//超过计划充电时间长
                kxEquipService.closeChannel(kxChargingRecordNew.getEquipNo(),kxChargingRecordNew.getChannelNo(),Constants.EndType.PlanChargingTime,true);
            }
        }
        // 是否允许欠费,不允许欠费。检查余额。
        if(!isOwe){
            BigDecimal lostBalance = BigDecimal.ZERO;
            if(kxChargingRecordNew.getUserId()!=0L){

                KxUserInfo account = kxUserInfoService.selectKxUserInfoByUserId(kxChargingRecordNew.getUserId());
                lostBalance = account.getBalance().add(account.getGive());
                logger.debug("用户ID："+kxChargingRecordNew.getUserId()+"判断余额是否足够,余额："+lostBalance+",消费金额："+kxChargingRecordNew.getAmount());
            }else {
                KxCard kxCard = kxCardService.selectKxCardByCardId(kxChargingRecordNew.getCardId());
                lostBalance = kxCard.getBalance().add(kxCard.getGive());
                logger.debug("电卡ID："+kxChargingRecordNew.getCardId()+"判断余额是否足够,余额："+lostBalance+",消费金额："+kxChargingRecordNew.getAmount());
            }
            // 余额减去消费金额如果小于0，则修改消费金额
            // 支持多用户充电后，判断该用户下所有的充电记录是否透支(获取用户充电消费总额)
            BigDecimal totalAmount = this.kxChargingRecordMapper.getTotalChargingRecordAmount(kxChargingRecordNew.getUserId());
            lostBalance = lostBalance.subtract(totalAmount);
            if(lostBalance.compareTo(BigDecimal.ZERO)==-1){// 根据情况抹除多消费的金额，目前暂定不超过0.2元的抹除
                if(lostBalance.compareTo(new BigDecimal("-0.2"))==1){
                    // 更新下金额最终消费金额
                    KxChargingRecord updateKxChargingRecord = new KxChargingRecord();
                    updateKxChargingRecord.setChargingRecordId(kxChargingRecordNew.getChargingRecordId());
                    updateKxChargingRecord.setAmount(kxChargingRecordNew.getAmount().add(lostBalance));
                    this.kxChargingRecordMapper.updateChargingPower(updateKxChargingRecord);
                    kxEquipService.closeChannel(kxChargingRecordNew.getEquipNo(),kxChargingRecordNew.getChannelNo(),Constants.EndType.BalanceNotEnough,true);
                }else {
                    kxEquipService.closeChannel(kxChargingRecordNew.getEquipNo(),kxChargingRecordNew.getChannelNo(),Constants.EndType.BalanceNotEnough,true);
                }
            }
        }

    }
}
